package com.gill.demo;

import org.apache.zookeeper.*;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.data.ACL;

import java.io.IOException;
import java.util.List;

/**
 *
 * @Description: zookeeper 同步异步创建zk节点demo演示
 */

public class ZKNodeCreate implements Watcher {

	private ZooKeeper zookeeper = null;
	
	public static final String zkServerPath = "env:2181";
	public static final Integer timeout = 5000;
	
	public ZKNodeCreate() {}
	
	public ZKNodeCreate(String connectString) {
		try {
			zookeeper = new ZooKeeper(connectString, timeout, new ZKNodeCreate());
		} catch (IOException e) {
			e.printStackTrace();
			if (zookeeper != null) {
				try {
					zookeeper.close();
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
			}
		}
	}
	
	/**
	 *
	 * @Description: 创建zk节点
	 */
	public void createZKNode(String path, byte[] data, List<ACL> acls) {
		
		String result = "";
		try {
			/**
			 * 同步或者异步创建节点，都不支持子节点的递归创建，异步有一个callback函数
			 * 参数：
			 * path：创建的路径
			 * data：存储的数据的byte[]
			 * acl：控制权限策略
			 * 			Ids.OPEN_ACL_UNSAFE --> world:anyone:cdrwa
			 * 			CREATOR_ALL_ACL --> auth:user:password:cdrwa
			 * createMode：节点类型, 是一个枚举
			 * 			PERSISTENT：持久节点
			 * 			PERSISTENT_SEQUENTIAL：持久顺序节点
			 * 			EPHEMERAL：临时节点
			 * 			EPHEMERAL_SEQUENTIAL：临时顺序节点
			 */
			//创建方式1：同步创建
//			result = zookeeper.create(path, data, acls, CreateMode.EPHEMERAL);
//			System.out.println("创建节点：\t" + result + "\t成功...");
//			new Thread().sleep(2000);//用来测试临时节点和持久节点（2s后断开连接，持久节点还存在，临时节点不存在 ）

			//创建方式2：异步创建
			String ctx = "{'create':'success'}";
			zookeeper.create(path, data, acls, CreateMode.PERSISTENT, new CreateCallBack(), ctx);
			new Thread().sleep(2000);//异步创建必须等到节点创建成功，可能回调函数不会获取到信息
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void process(WatchedEvent event) {
		// 连接成功后，连接时间触发，本次测试不做处理，所以采用空实现
	}

	public static void main(String[] args) throws Exception {
		// 建立连接，创建客户端
		ZKNodeCreate zkServer = new ZKNodeCreate(zkServerPath);

		// 创建zk节点
		zkServer.createZKNode("/testnode", "testnode".getBytes(), Ids.OPEN_ACL_UNSAFE);

	}

	/**
	 * 创建节点成功后，会自动获取节点的一些信息，执行processResult方法
	 */
	static class CreateCallBack implements AsyncCallback.StringCallback {

		@Override
		public void processResult(int rc, String path, Object ctx, String name) {
			System.out.println("创建节点: " + path);
			System.out.println((String)ctx);
		}

	}
}



